@* Generator: Template TypeVisibility: Internal *@
@using System.Globalization
@using System.IO
@using System.Web
@using System.Web.Mvc
@using Elmah
@inherits WebTemplateBase
@{
   
    var basePageName = Request.ServerVariables["URL"];
    
    //
    // Retrieve the ID of the error to display and read it from 
    // the store.
    //

    var errorId = Request.QueryString["id"] ?? string.Empty;

    if (errorId.Length == 0)
    { 
        return;
    }

    var log = this.ErrorLog ?? ErrorLog.GetDefault(Context);
    var errorEntry = log.GetError(errorId);

    //
    // Perhaps the error has been deleted from the store? Whatever
    // the reason, bail out silently.
    //

    if (errorEntry == null)
    {
        Response.Status = HttpStatus.NotFound.ToString();
        <p>Error not found in log.</p>
        return;
    }

    var title = string.Format("Error: {0} [{1}]", errorEntry.Error.Type, errorEntry.Id);

    Layout = new Elmah.MasterPage
    {
        Context  = Context, /* TODO Consider not requiring this */
        Title    = title,
        Footnote = string.Format("This log is provided by the {0}.", log.Name),
        SpeedBarItems = new[] 
        {
            SpeedBar.Home.Format(basePageName),
            SpeedBar.Help,
            SpeedBar.About.Format(basePageName),
        },
    };

    var error = errorEntry.Error;
    var url = "";
    var referer = "";

    if(null != error.ServerVariables && 0 != (error.ServerVariables["HTTP_HOST"] + "").Length){
        url = (error.ServerVariables["HTTPS"] != "on" ? "http://" : "https://")
                        + error.ServerVariables["HTTP_HOST"]
                        + error.ServerVariables["PATH_INFO"]
                        + (error.ServerVariables["QUERY_STRING"].Length == 0 ? "" : "?" + error.ServerVariables["QUERY_STRING"]);

        if (0 != (error.ServerVariables["HTTP_REFERER"] + "").Length)
        {
            referer = error.ServerVariables["HTTP_REFERER"];
        }
        
    }
       
}

@*
// Write out the page title containing error type and message.
*@

<h1 id="PageTitle">@error.Message</h1>
    <div id="errorUrl" class="alert-message">
@if (url.Length != 0)
{
        <span>url: </span><a id="ErrorUrl" target="_blank" href="@url">@url</a><br />
}
@if (referer.Length != 0)
{
        <span>referer: </span><a id="ErrorReferer" target="_blank" href="@referer">@referer</a><br />
}
    </div>
    <p id="ErrorTitle">@*
    *@<span id="ErrorType">@error.Type</span>@*
    *@<span id="ErrorTypeMessageSeparator">: </span>@*
    *@<span id="ErrorMessage">@error.Message</span>
    </p>

@*
// Do we have details, like the stack trace? If so, then write 
// them out in a pre-formatted (pre) element. 
// NOTE: There is an assumption here that detail will always
// contain a stack trace. If it doesn't then pre-formatting 
// might not be the right thing to do here.
*@

@if (error.Detail.Length != 0)
{
    <pre id="ErrorDetail">@MarkupStackTrace(error.Detail)</pre>
}

@*
// Write out the error log time. This will be in the local
// time zone of the server. Would be a good idea to indicate
// it here for the user.
*@

<p id="ErrorLogTime">@string.Format(
    @"Logged on {0} at {1}",
    error.Time.ToLongDateString(),
    error.Time.ToLongTimeString())</p>

@*
// Render alternate links.
*@

<p>See also:</p>

<ul>

@*
// Do we have an HTML formatted message from ASP.NET? If yes
// then write out a link to it instead of embedding it 
// with the rest of the content since it is an entire HTML
// document in itself.
*@

    @if (error.WebHostHtmlMessage.Length != 0)
    {
        var htmlUrl = basePageName + "/html?id=" + Uri.EscapeDataString(errorEntry.Id);
        <li><a href="@basePageName/html?id=@Uri.EscapeDataString(errorEntry.Id)">Original ASP.NET error page</a></li>
    }

@*
// Add a link to the source XML and JSON data.
*@
    <li>Raw/Source data in 
        <a rel="@HtmlLinkType.Alternate" 
           type="application/xml" 
           href="xml@(Request.Url.Query)">XML</a>
        or in
        <a rel="@HtmlLinkType.Alternate" 
           type="application/json" 
           href="json@(Request.Url.Query)">JSON</a>
    </li>
@{
    var ServerVariablesDisplay = new CollectionDisplayInfo { Data = error.ServerVariables, Id = "ServerVariables", Title = "Server Variables" };
    var FormDisplay = new CollectionDisplayInfo { Data = error.Form, Id = "Form", Title = "Form" };
    var CookiesDisplay = new CollectionDisplayInfo { Data = error.Cookies, Id = "Cookies", Title = "Cookies" };
    var SessionDisplay = new CollectionDisplayInfo { Data = error.Session, Id = "Session", Title = "Session" };
    var CacheDisplay = new CollectionDisplayInfo { Data = error.Cache, Id = "Cache", Title = "Cache" };
    var ApplicationStateDisplay = new CollectionDisplayInfo { Data = error.ApplicationState, Id = "ApplicationState", Title = "Application" };
        
}
    @if (null != ServerVariablesDisplay.Data)
    {<li><a href="#@ServerVariablesDisplay.Id">@ServerVariablesDisplay.Title</a></li>}
    @if (null != FormDisplay.Data)
    {<li><a href="#@FormDisplay.Id">@FormDisplay.Title</a></li>}
    @if (null != CookiesDisplay.Data)
    {<li><a href="#@CookiesDisplay.Id">@CookiesDisplay.Title</a></li>}
    @if (null != SessionDisplay.Data)
    {<li><a href="#@SessionDisplay.Id">@SessionDisplay.Title</a></li>}
    @if (null != CacheDisplay.Data)
    {<li><a href="#@CacheDisplay.Id">@CacheDisplay.Title</a></li>}
    @if (null != ApplicationStateDisplay.Data)
    {<li><a href="#@ApplicationStateDisplay.Id">@ApplicationStateDisplay.Title</a></li>}
</ul>
@RenderCollection(new CollectionDisplayInfo { Data = error.ServerVariables, Id = "ServerVariables", Title = "Server Variables" })
@RenderCollection(new CollectionDisplayInfo { Data = error.Form, Id = "Form", Title = "Form" })
@RenderCollection(new CollectionDisplayInfo { Data = error.Cookies, Id = "Cookies", Title = "Cookies" })
@RenderCollection(new CollectionDisplayInfo { Data = error.Session, Id = "Session", Title = "Session" })
@RenderCollection(new CollectionDisplayInfo { Data = error.Cache, Id = "Cache", Title = "Cache" })
@RenderCollection(new CollectionDisplayInfo { Data = error.ApplicationState, Id = "ApplicationState", Title = "Application" })

    
@helper RenderCollection(CollectionDisplayInfo collection)
{
    //Debug.Assert(writer != null);
    //Debug.AssertStringNotEmpty(id);
    //Debug.AssertStringNotEmpty(title);

    //
    // If the collection isn't there or it's empty, then bail out.
    //

    if (collection.Data != null)
    {
        var items = new System.Collections.Generic.List<CollectionDisplayInfoItem>();
        if(collection.Data is System.Collections.Specialized.NameValueCollection){
            items =
                (from i in Enumerable.Range(0, ((System.Collections.Specialized.NameValueCollection)collection.Data).Count)
                select new CollectionDisplayInfoItem()
                {
                    Index = i,
                    Key = ((System.Collections.Specialized.NameValueCollection)collection.Data).GetKey(i),
                    Value = ((System.Collections.Specialized.NameValueCollection)collection.Data)[i],
                }).OrderBy(e => e.Key, StringComparer.OrdinalIgnoreCase).ToList();                    
        }
            
            
            
        <div id="@collection.Id">
            <a name="@collection.Id"></a>
            <h2>@collection.Title</h2>
            @*
            // Some values can be large and add scroll bars to the page
            // as well as ruin some formatting. So we encapsulate the
            // table into a scrollable view that is controlled via the 
            // style sheet.
            *@

            <div class="scroll-view">

                <table cellspacing="0" style="border-collapse:collapse;" class="condensed-table zebra-striped">
                    <tr>
                        <th class="name-col" style="white-space:nowrap;">Name</th>
                        <th class="value-col" style="white-space:nowrap;">Value</th>
                    </tr>
    
                    @foreach (var item in items)
                    {
                        <tr class="@(item.Index % 2 == 0 ? "even" : "odd")">
                            <td class="key-col">@item.Key</td>
                            <td class="value-col">@item.Value</td>
                        </tr>
                    }

                </table>
            </div>
        </div>
    }
}
